package com.zsqat.eshop.product.feign;

import com.zsqat.common.to.SkuReductionTo;
import com.zsqat.common.to.SpuBoundTo;
import com.zsqat.common.utils.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient("eshop-coupon")
public interface CouponFeignService {

  /**
   * CouponFeignService.saveSpuBounds(spuBoundTo);
   *      1). @RequestBody将这个对象转为json。
   *      2). 找到eshop-coupon服务，给/coupon/spubounds/save发送请求。
   *          将上一步转的json放在请求体位置，发送请求；
   *      3). 对方服务收到请求。请求体里有json数据。
   *          (@RequestBody SpuBoundsEntity spuBounds)；将请求体的json转为SpuBoundsEntity；
   * 只要json数据模型是兼容的。双方服务无需使用同一个类。
   * 总结：
   *   在openfen中会将调用的数据转换为JSON，接收方接收后，将JSON转换为对象，
   *   此时调用方和被调用方的处理JSON的对象不一定都是同一个类，只要它们的字段类型吻合即可。
   * @param spuBoundTo
   * @return
   */
  @PostMapping("/coupon/spubounds/save")
  R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);

  @PostMapping("/coupon/skufullreduction/saveinfo")
  R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);
}
/*
基础知识介绍：
   1.@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)；
     GET方式无请求体，所以使用@RequestBody接收数据时，前端不能使用GET方式提交数据，而是用POST方式进行提交。
   2.在后端的同一个接收方法里，@RequestBody与@RequestParam()可以同时使用，@RequestBody最多只能有一个，
     而@RequestParam()可以有多个。


   注: 当同时使用@RequestParam()和@RequestBody时，@RequestParam()指定的参数可以是普通元素、
       数组、集合、对象等等(即:当，@RequestBody 与@RequestParam()可以同时使用时，原SpringMVC接收
       参数的机制不变，只不过RequestBody 接收的是请求体里面的数据；而RequestParam接收的是key-value
       里面的参数，所以它会被切面进行处理从而可以用普通元素、数组、集合、对象等接收)。

       即：如果参数时放在请求体中，application/json传入后台的话，那么后台要用@RequestBody才能接收到；
          如果不是放在请求体中的话，那么后台接收前台传过来的参数时，要用@RequestParam来接收。

   注: 如果参数前写了@RequestParam(xxx)，那么前端必须有对应的xxx名字才行(不管其是否有值，当然可以通
       过设置该注解的required属性来调节是否必须传)，如果没有xxx名的话，那么请求会出错，报400。

   注: 如果参数前不写@RequestParam(xxx)的话，那么就前端可以有可以没有对应的xxx名字才行，如果有xxx名
       的话，那么就会自动匹配；没有的话，请求也能正确发送。

   追注: 这里与feign消费服务时不同；feign消费服务时，如果参数前什么也不写，那么会被默认是@RequestBody的。

   如果后端参数是一个对象，且该参数前是以@RequestBody修饰的，那么前端传递json参数时，必须满足以下要求:

   后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即：@RequestBody后面的类)时，
   会根据json字符串中的key来匹配对应实体类的属性，如果匹配一致且json中的该key对应的值符合(或可转换为)实体类的对应属性的类型要求时,
   会调用实体类的setter方法将值赋给该属性。
   1). json字符串中，如果value为""的话，后端对应属性如果是String类型的，那么接受到的就是""，
       如果是后端属性的类型是Integer、Double等类型，那么接收到的就是null。

   2). json字符串中，如果value为null的话，后端对应收到的就是null。

   3). 如果某个参数没有value的话，在传json字符串给后端时，要么干脆就不把该字段写到json字符串中,
       要么写value时,必须有值 null 或 "" 都行。
 */